// #ifdef H5
import Fly from 'flyio/dist/npm/fly'
// #endif

// #ifdef APP-PLUS
import Fly from 'flyio/dist/npm/wx'
// #endif

// #ifdef MP-WEIXIN
import Fly from 'flyio/dist/npm/wx'
// #endif
// #ifdef MP-ALIPAY
import Fly from 'flyio/dist/npm/ap'
// #endif
import store from '../store'
import { handleLoginFailure } from '@/utils'
import { VUE_APP_API_URL,VUE_APP_REGISTER_CANAL } from '@/config'
import cookie from '@/utils/store/cookie'
import { v4 as uuidv4 } from 'uuid';
import { encryptLong, decryptLong, syShopSign } from '@/utils/rsaEncrypt'

const fly = new Fly()
fly.config.baseURL = VUE_APP_API_URL
const timeStamp = new Date().getTime();
fly.interceptors.response.use(
  response => {
    // 定时刷新access-token
    return response
  },error => {
	if(error.message=='Network Error'){
		uni.showModal({
			title: '提示',
			content: '检测到您发送的请求是跨站伪造请求',
			success: function (res) {
				if (res.confirm) {
					console.log('用户点击确定');
				} else if (res.cancel) {
					console.log('用户点击取消');
				}
			}
		});
		return Promise.reject("10010")
	}
    if (error.toString() == 'Error: Network Error') {
      console.log('请求失败', error)
      handleLoginFailure()
      return Promise.reject({ msg: '未登录', toLogin: true })
    }
    if (error.status == 401) {
      console.log('登录失效 401', error)
      handleLoginFailure()
      return Promise.reject({ msg: '未登录', toLogin: true })
    }
    if (error.response.data.status == 5109) {
      uni.showToast({
        title: error.response.data.msg,
        icon: 'none',
        duration: 2000,
      })
    }
    return Promise.reject(error)
  }
)

const defaultOpt = { login: true }

function baseRequest(options) {
	// 从缓存中获取 token 防止 token 失效后还会继续请求的情况
	const token = cookie.get('login_status')
	// 合并传参过来的 headers
	// 如果接口需要登录，携带 token 去请求
	const timeStamp = new Date().getTime();
	const sySign = syShopSign();
	const nonce = uuidv4();
	let version = "1.0.0";
	// #ifdef APP-PLUS
	const systemInfo = uni.getSystemInfoSync();
	version = systemInfo.appWgtVersion;
	// #endif
    options.headers = {
      ...options.headers,
  	Authorization: 'Bearer ' + token,
  	'TimeStamp': String(timeStamp),
	'nonce':nonce,
  	'CheckCsrf':encryptLong(sySign + timeStamp + nonce),
	'RegisterCanal':VUE_APP_REGISTER_CANAL,
	'Version':version,	
    }
  if (options.login === true) {
    options.headers = {
      ...options.headers,
      Authorization: 'Bearer ' + token,
    }
  }

  // 结构请求需要的参数
  const { url, params, data, login, ...option } = options
  // 发起请求
  return fly.request(url, params || data, {
      ...option,
    }).then(res => {
		 let data = res.data || {}
		// #ifdef MP-ALIPAY
		const systemInfo = uni.getSystemInfoSync();
		const isAndroid = systemInfo.platform === 'android';
		console.log(isAndroid ? '当前设备是安卓机' : '当前设备不是安卓机');
		if (isAndroid) {
			data = JSON.parse(res.data) || {}
			res.data = data
		}
		// #endif
      if (res.status !== 200) {
        return Promise.reject({ msg: '请求失败', res, data })
      }
      if ([401, 403].indexOf(data.status) !== -1) {
        handleLoginFailure()
        return Promise.reject({ msg: res.data.msg, res, data, toLogin: true })
      } else if (data.status === 200) {
        return Promise.resolve(data, res)
      } else if (data.status == 5101) {
        return Promise.reject({ msg: res.data.msg, res, data })
      } else {
        return Promise.reject({ msg: res.data.msg, res, data })
      }
    })
}
const request = ['post', 'put', 'patch'].reduce((request, method) => {
  /**
   * @param url string 接口地址
   * @param data object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, data = {}, options = {}) => {
    return baseRequest(Object.assign({ url, data, method }, defaultOpt, options))
  }
  return request
}, {});

['get', 'delete', 'head'].forEach(method => {
  /**
   * @param url string 接口地址
   * @param params object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, params = {}, options = {}) => {
    return baseRequest(Object.assign({ url, params, method }, defaultOpt, options))
  }
})

export default request
